#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include "comm.h"


unsigned long print_time(){
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000000 + tv.tv_usec;
}

void print_help()
{
	printf(
		"星海数据库，请使用正确的参数，参考如下：\n"\
		"\tsearch [rowkey]            采用rowkey进行记录查询\n"\
		"\tinsert [rowkey] [values]   插入数据，包括rowkey及自定义数值\n"\
		"\tserver                     开启HTTP server服务\n"
	);
	
}

BYTE* row_insert(BYTE *key, BYTE *values){
	int fd;
	fd = open("./swap.data", O_RDWR);
	if (0 == fd){
		/* open file fail */
		PRINTF("open swap failed\n");
		return NULL;
	}
	/* move to end of file */
	lseek(fd, 0, SEEK_END);
	write(fd, key, strlen(key));
	write(fd, ", ", 2);
	write(fd, values, strlen(values));
	write(fd, "\n", 1);
	return NULL;	
	close(fd);
}

BYTE* row_scan(BYTE* key){
	BYTE *start, *end;
	size_t fsize;
	BYTE *c;
	BYTE *result=NULL;
	
	start = open_file("./swap.data", &fsize);
	if (NULL == start){
		return NULL;
	}
	end = start + fsize;
	
	c = start;
	while (c != end){
		// printf("c = %p\n", c);
		BYTE *line_end, *key_end, *line_start;
		line_start = c;
		while(*c != ',' && c != end){
			// printf("while 1 c = %p v=%c\n", c, *c);
			c++;
		}
		key_end = c;
		while(*c != '\n' && c != end){
			// printf("while 2 c = %p\n", c);
			c++;
		}
		
		if (c!=end && !memcmp(key, line_start, key_end - line_start)){	
			/* HIT */
			result = line_start;
			// PRINTF("SCAN HIT %s!", key);
			// PRINT_LINE(line_start);
		}
		if (*c == '\n') c++;
	}
	return result;
}

BYTE* row_search(BYTE *key){
	BYTE* pFile;
	size_t fsize;
	unsigned long logtime;
	char filename[100];
	BYTE* result1 = NULL;
	BYTE* result2 = NULL;
	
	/* key to file name */
	unsigned long nKey = atol(key);
	unsigned long nFile = (nKey/8000000)*8000000;
	sprintf(filename, "./%ld.data", nFile);
	PRINTF("search key = %ld, nfile = %ld\n", nKey, nFile);
	/**************************************
	STEP 1: read file, map file to memory;
	***************************************/
	logtime = print_time();
	PRINTF("search key %s", key);
	pFile = open_file(filename, &fsize);
	if (pFile){
		PRINTF("read file success, size = %ld\n", fsize);
		result1 = split_search(pFile, fsize, key);
	}
	
	result2 = row_scan(key);
	if (result2){
		PRINTF("HIT! RESULT = ");
		PRINT_LINE(result2);
	}else if (result1){
		PRINTF("HIT! RESULT = ");
		PRINT_LINE(result1);
	}else{
		PRINTF("MISS!");
	}
	
	logtime = print_time();
	return 0;
}

int count_swap(){
	BYTE *start, *end;
	size_t fsize;
	BYTE *c;
	BYTE *result=NULL;
	int  count=0;
	
	start = open_file("./swap.data", &fsize);
	if (NULL == start){
		return 0;
	}
	end = start + fsize;

	while (c != end){
		if (*c == '\n') {
			count++;
		}
		c++;
	}
	return count;
}

int main(int argc, char *argv[])
{	
	if (argc == 3){
		if (!strcmp(argv[1], "search")){
			row_search(argv[2]);
			return 0;
		}
	}
	
	if (argc == 4){
		if (!strcmp(argv[1], "insert")){
			row_insert(argv[2], argv[3]);
			return 0;
		}
	}
	
	if (argc == 2){
		if (!strcmp(argv[1], "count")){
			printf("Total count is %ld\n", 0+count_swap);
			return 0;
		}
	}
	
	print_help();
	return 0;
}

